package com.iflytek.jcy.supervise.clue.service.impl;

import com.iflytek.jcy.supervise.clue.common.pojo.MongoPageResult;
import com.iflytek.jcy.supervise.clue.dto.QueryClueDetailDTO;
import com.iflytek.jcy.supervise.clue.dto.response.InfoDTO;
import com.iflytek.jcy.supervise.clue.dto.response.InfoPageDTO;
import com.iflytek.jcy.supervise.clue.entity.TaskDetail;
import com.iflytek.jcy.supervise.clue.mapper.TaskDetailMapper;
import com.iflytek.jcy.supervise.clue.service.MongoService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.*;

/** <br>
 * 标题:mongoDB服务实现类 <br>
 * 描述: <br>
 * 公司: www.iflytek.com<br>
 * 
 * @autho dgyu
 * @time 2022年11月5日 下午4:03:08 */
@Service
public class MongoServiceImpl implements MongoService {

	private static final Logger	logger = LoggerFactory.getLogger(MongoServiceImpl.class);

	@Autowired
	MongoTemplate				mongoTemplate;
	@Autowired
	private TaskDetailMapper	taskDetailMapper;
	@Value("${spring.data.mongodb.collection}")
	private String collectionName;
	/** MongDb分页公共方法
	 * 
	 * @param clazz
	 *        实体类的class对象
	 * @param pageSize
	 *        每页的数量
	 * @param pageNo
	 *        当前的页数
	 * @param query
	 *        query是啥不知道赶紧去查下，相当于sql语句
	 * @return */
	public MongoPageResult<InfoPageDTO> pagination(Class<InfoDTO> clazz, int pageSize, int pageNo, Query query) {
		long total = this.count(query, clazz);
		Integer pages = (int) Math.ceil((double) total / (double) pageSize);
		if (pageNo <= 0 || pageNo > pages) {
			pageNo = 1;
		}
		int skip = pageSize * (pageNo - 1);
		query.skip(skip).limit(pageSize);
		List<InfoDTO> list = mongoTemplate.find(query, clazz,collectionName);
		MongoPageResult pageResult = new MongoPageResult();
		pageResult.setTotal(total);
		pageResult.setPages(pages);
		pageResult.setPageSize(pageSize);
		pageResult.setPageNo(pageNo);
		if (CollectionUtils.isEmpty(list)) {
			return pageResult;
		}
		pageResult.setColumns(list.get(0).getNames());
		// pageResult.setList(list);
		List<InfoPageDTO> infoDTOList = new ArrayList<>(list.size());
		list.forEach(v -> {
			InfoPageDTO infoPageDTO = new InfoPageDTO();
			BeanUtils.copyProperties(v, infoPageDTO);
			List<String> names = v.getNames();
			List<String> values = v.getValues();
			LinkedHashMap<String, String> map = new LinkedHashMap<>();
			for (int i = 0; i < names.size(); i++) {
				String name = names.get(i);
				String value = values.get(i);
				map.put(name, value);
			}
			infoPageDTO.setMap(map);
			infoDTOList.add(infoPageDTO);
		});
		pageResult.setData(infoDTOList);
		return pageResult;
	}

	@Override
	public MongoPageResult<InfoPageDTO> info(QueryClueDetailDTO queryClueDetailDTO) {
		Integer pageNo = queryClueDetailDTO.getPageNo();
		Integer pageSize = queryClueDetailDTO.getPageSize();
		if (pageNo < 1) {
			pageNo = 1;
		}
		Query query = new Query();
		Criteria criteria = new Criteria();
		List<Criteria> andCriterias = new ArrayList<>();
		// 查询条件
		if(CollectionUtils.isNotEmpty(queryClueDetailDTO.getTaskLogIds())) {
			Criteria c = Criteria.where("taskLogId").in(queryClueDetailDTO.getTaskLogIds());
			andCriterias.add(c);
		}
		if (CollectionUtils.isNotEmpty(queryClueDetailDTO.getIds())) {
			Criteria c = Criteria.where("_id").in(queryClueDetailDTO.getIds());
			andCriterias.add(c);
		}
		if (queryClueDetailDTO.getTaskLogId() != null && queryClueDetailDTO.getTaskLogId() > 0) {
			Criteria c = Criteria.where("taskLogId").is(queryClueDetailDTO.getTaskLogId());
			andCriterias.add(c);
		}
		if (queryClueDetailDTO.getPointId() != null && queryClueDetailDTO.getPointId() > 0) {
			Criteria c = Criteria.where("pointId").is(queryClueDetailDTO.getPointId());
			andCriterias.add(c);
		}
		criteria.andOperator(andCriterias.toArray(new Criteria[0]));
		query.addCriteria(criteria);
		// 排序字段
		Sort orderBySort = Sort.by(Sort.Direction.DESC, "createTime","reportObjectName","reportObjectName"); // 倒序
		Pageable pageable = PageRequest.of(pageNo, pageSize, orderBySort);
		query.with(pageable);
		// mongoTemplate.find 查询结果集
		return pagination(InfoDTO.class, pageSize, pageNo, query);
	}

	@Override
	public InfoPageDTO info(Integer id) {
		InfoDTO infoDTO = this.mongoTemplate.findById(id, InfoDTO.class,collectionName);
		if (null == infoDTO) {
			return null;
		}
		InfoPageDTO infoPageDTO = new InfoPageDTO();
		BeanUtils.copyProperties(infoDTO, infoPageDTO);
		List<String> names = infoDTO.getNames();
		List<String> values = infoDTO.getValues();
		LinkedHashMap<String, String> map = new LinkedHashMap<>();
		for (int i = 0; i < names.size(); i++) {
			String name = names.get(i);
			String value = values.get(i);
			map.put(name, value);
		}
		infoPageDTO.setMap(map);
		TaskDetail taskDetail = this.taskDetailMapper.selectById(id);
		if (null != taskDetail) {
			infoPageDTO.setExceptionLogic(taskDetail.getExceptionLogic());
			infoPageDTO.setExceptionTypeDesc(taskDetail.getExceptionTypeDesc());
		}
		return infoPageDTO;
	}

	// 修改计数方法解决分页总数出错
	public Long count(Query query, Class clazz) {
		/** 注意：查询偏移量(offset)和限制条数(limit)可能会直接影响最终查询文档的数量，因为这些值会传递到服务器， 并可能限制服务器执行计数操作的范围和顺序。所以要使用没有分页数据的对象来查。 */
		BasicQuery basicQuery = new BasicQuery(query.getQueryObject().toJson());
		return mongoTemplate.count(basicQuery, clazz,collectionName);
	};
}
